#pragma region Licensing
/*
       LOGL::GLib -> LorgonJortle's OpenGL Game Library
       Copyright (C) 2011  Jesse 'LorgonJortle' Wilkerson

       This program is free software: you can redistribute it and/or modify
       it under the terms of the GNU General Public License as published by
       the Free Software Foundation, either version 3 of the License, or
       (at your option) any later version.

       This program is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       GNU General Public License for more details.

       You should have received a copy of the GNU General Public License
       along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#pragma endregion

#include "Keyboard.h"

namespace LOGL_GLib
{
     namespace Input
     {
          /* Declare the static variables in the .cpp scope. */
          std::bitset<SDLK_LAST> Keyboard::currentKeystate;
          std::bitset<SDLK_LAST> Keyboard::previousKeystate;
          GLvoid (*Keyboard::keyFunc)(Key _Key, KeyState _State) = 0;

          /******************************************************************************
           static GLboolean Keyboard::Initialize();
                    Arguments:
                         void

                    Description:
                         Initializes the keystate buffers and prepares to handle input.

                    Returns:
                         Whether or not the keyboard initialized successfully.
          *******************************************************************************/
          GLvoid Keyboard::Initialize()
          {
               /* Set the keystate buffers to zeros. */
               currentKeystate.reset();
               previousKeystate.reset();
          }

          /******************************************************************************
           static GLvoid Keyboard::SwapBuffers();
                    Arguments:
                         void

                    Description:
                         Swaps the current/previous keystate buffers.

                    Returns:
                         void
          *******************************************************************************/
          GLvoid Keyboard::SwapBuffers()
          {
               /* Set the previous buffer the the current one. */
               previousKeystate = currentKeystate;
          }

          /******************************************************************************
           static GLboolean Keyboard::IsKeyDown(Key _Key);
                    Arguments:
                         Key _Key:
                              The key flag to query.

                    Description:
                         Checks if a key is currently pressed.

                    Returns:
                         Whether or not the specified key is currently pressed.
          *******************************************************************************/
          GLboolean Keyboard::IsKeyDown(Key _Key)
          {
               return currentKeystate.test(_Key);
          }

          /******************************************************************************
           static GLboolean Keyboard::WasKeyDown(Key _Key);
                    Arguments:
                         Key _Key:
                              The key flag to query.

                    Description:
                         Checks if a key was pressed last update.

                    Returns:
                         Whether or not the specified key was pressed last update.
          *******************************************************************************/
          GLboolean Keyboard::WasKeyDown(Key _Key)
          {
               return previousKeystate.test(_Key);
          }

          /******************************************************************************
           static GLboolean Keyboard::IsNewKeyDown(Key _Key);
                    Arguments:
                         Key _Key:
                              The key flag to query.

                    Description:
                         Checks if a key is down that wasn't down last update.

                    Returns:
                         Whether or not the specified key is currently down and that it
                         wasn't down last update.
          *******************************************************************************/
          GLboolean Keyboard::IsNewKeyDown(Key _Key)
          {
               return (currentKeystate.test(_Key) && !previousKeystate.test(_Key));
          }

          /******************************************************************************
           static GLvoid Keyboard:KeyDown(GLint _Key);
                    Arguments:
                         GLint _Key:
                              The key flag to set to false.

                    Description:
                         Sets the status of the specified key to pressed (down).

                    Returns:
                         void
          *******************************************************************************/
          GLvoid Keyboard::KeyDown(GLint _Key)
          {
               currentKeystate.set(_Key, 1);

               /* Acknowledge any callback. */
               if(keyFunc != 0)
                    keyFunc((Key)_Key, (KeyState)Key_Pressed);
          }

          /******************************************************************************
           static GLvoid Keyboard:KeyUp(GLint _Key);
                    Arguments:
                         GLint _Key:
                              The key flag to set to false.

                    Description:
                         Sets the status of the specified key to unpressed (up).

                    Returns:
                         void
          *******************************************************************************/
          GLvoid Keyboard::KeyUp(GLint _Key)
          {
               currentKeystate.set(_Key, 0);

               /* Acknowledge any callback. */
               if(keyFunc != 0)
                    keyFunc((Key)_Key, (KeyState)Key_Released);
          }

          /******************************************************************************
           static GLvoid Keyboard:KeyFunc(GLvoid (*_KeyFunc)(Key _Key,
                                                             KeyState _State));
                    Arguments:
                         GLvoid (*_KeyFunc)(Key _Key, KeyState _State):
                              A function pointer to a callback for when a key action occurs.

                    Description:
                         Sets the key action callback.

                    Returns:
                         void
          *******************************************************************************/
          GLvoid Keyboard::KeyFunc(GLvoid (*_KeyFunc)(Key _Key, KeyState _State))
          {
               keyFunc = _KeyFunc;
          }
     } /* Namespace Input. */
} /* Namespace LOGL_GLib. */
